package com.yuandian.middle.platform.contoller;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.yuandian.api.middle_platform.po.IndicatorReportingParam;
import com.yuandian.api.middle_platform.vo.OperationalIndicatorResultVo;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.middle.platform.service.IIndicatorReportingService;
import com.yuandian.utils.PageDataInfo;
import com.yuandian.utils.YDateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

/**
 * 说明：指标上报(中台二期)
 * @Author LSH
 * @Date 2023/5/23 13:58
 */
@Api(value = "indicatorReporting", tags = "指标上报接口")
@RestController
@RequestMapping("/modules/indicatorReporting")
@Slf4j
@RefreshScope
public class IndicatorReportingController {

	/** 运营指标上报开关 */
	@Value("${reporting.operations-flag}")
	private boolean operationsFlag;

	/** 实时指标上报开关 */
	@Value("${reporting.realTime-flag}")
	private boolean realTimeFlag;

    @Autowired
    private IIndicatorReportingService serverDetailService;

	/**
	 * 查询运营指标
	 * @param param	请求参数
	 * @return	通用结果集
	 */
    @PostMapping("/queryOperationalIndicators")
    @ApiOperation(value = "查询运营指标", notes = "查询运营指标")
    public R<OperationalIndicatorResultVo> queryOperationalIndicators(@RequestBody IndicatorReportingParam param) {
        if (StringUtils.isBlank(param.getServiceCode())) { return R.failed("服务编码(serviceCode)不能为空"); }
        return serverDetailService.queryOperationalIndicators(param);
    }

	/**
	 * 查询实时指标
	 * @param param	请求参数
	 * @return	通用结果集
	 */
	@PostMapping("/queryImplementationIndicators")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "abilityCode", 		value = "能力编码", 		paramType = "body", required = true, 	dataType = "Integer", 		dataTypeClass = Integer.class),
			@ApiImplicitParam(name = "serviceCode", 		value = "服务编码", 		paramType = "body", required = false, 	dataType = "String", 		dataTypeClass = String.class),
			@ApiImplicitParam(name = "userOrgName", 		value = "使用方名称", 	paramType = "body", required = false, 	dataType = "String", 		dataTypeClass = String.class),
			@ApiImplicitParam(name = "pageNum",   			value = "页码", 			paramType = "query", required = true,  dataType = "Long"),
			@ApiImplicitParam(name = "pageSize", 			value = "每页大小", 		paramType = "query", required = true,  dataType = "Long"),
			@ApiImplicitParam(name = "startTime", 			value = "开始时间", 		paramType = "query", required = true,  dataType = "String"),
			@ApiImplicitParam(name = "endTime",   			value = "结束时间", 		paramType = "query", required = true,  dataType = "String")
	})
	@ApiOperation(value = "查询实时指标", notes = "查询实时指标")
	public R<PageDataInfo> queryImplementationIndicators(@RequestBody IndicatorReportingParam param) {

		return serverDetailService.queryImplementationIndicators(param);
	}

	/**
	 * 运营 指标-导出
	 * @param param	请求参数
	 */
	@PostMapping("/queryOperationalDown")
	@ApiOperation(value = "运营 指标-导出", notes = "运营 指标指标-导出")
	public void queryOperationalDown(@RequestBody IndicatorReportingParam param,
									HttpServletResponse response) throws IOException {

		param.setPageNum(1);
		param.setPageSize(-1);
		serverDetailService.queryOperationalDown(param, response);
	}


	/**
	 * 实时 指标-导出
	 * @param param	请求参数
	 */
	@PostMapping("/queryImplementationDown")
	@ApiOperation(value = "实时 指标-导出", notes = "实时 指标指标-导出")
	public void queryImplementationDown(@RequestBody IndicatorReportingParam param,
									HttpServletResponse response) throws IOException {

		param.setPageNum(1);
		param.setPageSize(-1);
		serverDetailService.queryImplementationDown(param, response);

	}


// ====================================== 指标上报定时任务 ============================================================



	/**
	 * 手动触发 运营 指标上报
	 */
	@GetMapping("/operationalReporting")
	public R<Object> operationalReporting() throws IOException {
		log.info("运营指标-数据上报:手动上报-开始");

		operationalFileReporting();

		log.info("运营指标-数据上报:手动上报-结束");

		return R.ok();
	}


	/**
	 * 自动 触发 运营 指标上报
	 */
	@Scheduled(cron ="0 0 14 * * ?")
	public void operationalReportingAutomatic() throws IOException {
		if (operationsFlag) {
			operationalFileReporting();
		} else {
			log.warn("运营指标-数据上报:自动上报尚未开启, operationsFlag: {}", operationsFlag);
		}
	}



	/**
	 * 运营指标上报
	 */
	public void operationalFileReporting() {
		Date date = new Date();
		// 1.计算 startTime 和 endTime
		String startTime = YDateUtil.yyyy_MM_dd_000000(YDateUtil.yesterday().toString());
		String endTime = YDateUtil.yyyy_MM_dd_000000(YDateUtil.formatDateTime(date));

		// 2.设置参数
		IndicatorReportingParam param = new IndicatorReportingParam();
		param.setStartTime(startTime);
		param.setEndTime(endTime);

		try {
			// 3.开始上报
			long sTime = System.currentTimeMillis();
			log.info("运营指标-数据上报-开始，任务执行时间：{}, 数据开始时间：{}， 数据结束时间：{}", YDateUtil.formatDateTime(new Date()), startTime, endTime);
			serverDetailService.operationalFileReporting(param);
			log.info("运营指标-数据上报-结束，耗时：{} MS", System.currentTimeMillis() - sTime);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("运营指标-数据上报-报错: {}", e.getMessage());
		}
	}


	/**
	 * 手动触发 运营 指标上报
	 */
	@GetMapping("/realTimeReporting")
	public R<Object> realTimeReporting() throws IOException {
		log.info("实时指标-数据上报:手动上报-开始");

		realTimeFileReporting();

		log.info("实时指标-数据上报:手动上报-结束");

		return R.ok();
	}


	/**
	 * 自动 触发 运营 指标上报
	 */
	@Scheduled(cron ="0 0/15 * * * ? ")
	public void realTimeReportingAutomatic() {
		if (realTimeFlag) {
			realTimeFileReporting();
		} else {
			log.warn("实时指标-数据上报:自动上报尚未开启, realTimeFlag: {}", realTimeFlag);
		}
	}



	/**
	 * 实时指标上报
	 */

	public void realTimeFileReporting() {
		Date date = new Date();
		// 1.计算 endTime: 先计算当前时间数据哪个十五分钟内的范畴(如 9:46-9:59 属于 9:45 范畴)，再往前推十五分钟得到endTime
		Date endTimeDate = YDateUtil.getBeforeMinute(date, (YDateUtil.getMinute(date) % 15) + 15);
		String endTime = YDateUtil.format(endTimeDate, "yyyy-MM-dd HH:mm:00");

		// 2.计算 startTime: 把endTime往前推十五分钟
		Date startTimeDate = YDateUtil.getBeforeMinute(endTimeDate, 15);
		String startTime = YDateUtil.format(startTimeDate, "yyyy-MM-dd HH:mm:00");

		// 3.设置参数
		IndicatorReportingParam param = new IndicatorReportingParam();
		param.setStartTime(startTime);
		param.setEndTime(endTime);

		try {
			// 4.开始上报
			long sTime = System.currentTimeMillis();
			log.info("实时指标-数据上报-开始，任务执行时间：{}, 数据开始时间：{}， 数据结束时间：{}", YDateUtil.formatDateTime(new Date()), startTime, endTime);
			serverDetailService.implementationIndicators(param);
			log.info("实时指标-数据上报-结束，耗时：{} MS", System.currentTimeMillis() - sTime);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("实时指标-数据上报-报错: {}", e.getMessage());
		}
	}

}

